package com.hyts.classcode.classload.load;

import com.hyts.classcode.classload.config.ClassloaderConfig;
import lombok.Getter;
import lombok.Setter;

import java.net.URL;

/**
 * project-name:coffice-toolbox
 * package-name:com.hyts.classloader.load
 * author:Libo/Alex
 * create-date:2019-05-18 13:02
 * copyright:libo-hyts-github
 * email:libo2dev@aliyun.com
 * description:此类主要用于: 系统采用模板模式或者门面模式进行控制不同的classLoader服务
 */
//@AllArgsConstructor
public abstract class AbstractClassLoader extends ClassLoader {


    /**
     * 主要为系统compile之后的生产class文件字节码的路径根目录
     */
    @Getter
    @Setter
    private String compilePath;

    @Getter
    private final ClassLoader classLoader;

    /**
     * @param classLoader 指定的classloader父类的类加载器
     */
    public AbstractClassLoader(ClassLoader classLoader){
        super(classLoader);
        this.compilePath = compilePath == null ?ClassloaderConfig.DEFAULT_CLASS_COMPILER_PATH:compilePath;
        this.classLoader = classLoader;
    }

    /**
     * 当前类加载器为父类-系统加载器
     */
    public AbstractClassLoader(){
        super(AbstractClassLoader.class.getClassLoader());
        this.compilePath = compilePath == null ?ClassloaderConfig.DEFAULT_CLASS_COMPILER_PATH:compilePath;
        this.classLoader = AbstractClassLoader.class.getClassLoader();
    }

    /**
     * @param compilePath
     * @param classLoader
     */
    public AbstractClassLoader(String compilePath,ClassLoader classLoader){
        super(Thread.currentThread().getContextClassLoader());
        this.compilePath = compilePath == null ? ClassloaderConfig.DEFAULT_CLASS_COMPILER_PATH:compilePath;
        this.classLoader = AbstractClassLoader.class.getClassLoader();
    }

    /**
     * 用户必须要考虑search
     * @param name class execute main class type file name
     *             attention：not have .java or .class
     * @return
     */
    public abstract Class<?> searchClassObject(String name);

    /**
     * @param name
     * @param path user self definition compilerPath
     * @return
     */
    @Deprecated
    public abstract Class<?> searchClassObjectByPath(String name,String path);


    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        return searchClassObject(name);
    }

    @Override
    public URL getResource(String name) {
        return super.getResource(name);
    }

    @Override
    protected URL findResource(String name) {
        return super.findResource(name);
    }

    @Override
    protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) throws IllegalArgumentException {
        return super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
    }

    @Override
    protected String findLibrary(String libname) {
        return super.findLibrary(libname);
    }
}
